package com.stars.easyms.demo.rest.service.sentinel;

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.Tracer;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.stars.easyms.demo.rest.dto.input.sentinel.SentinelDemo4Input;
import com.stars.easyms.demo.rest.dto.output.sentinel.SentinelDemo4Output;
import com.stars.easyms.rest.RestService;
import com.stars.easyms.base.util.MessageFormatUtil;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class SentinelDemo4Service implements RestService<SentinelDemo4Input, SentinelDemo4Output> {

    private static final String RESOURCE_NAME = SentinelDemo4Service.class.getSimpleName();

    @Override
    public SentinelDemo4Output execute(SentinelDemo4Input input) {
        defineDegradeRule(input);
        int successCount = 0, blockCount = 0, exceptionCount = 0;
        for (int i = 0; i < input.getTimes(); i++) {
//            try (Entry entry = SphU.entry(RESOURCE_NAME)) {
//                successCount++;
//                if (i % 2 == 0) {
//                    throw new RuntimeException("throw runtime ");
//                }
//            } catch (BlockException e1) {
//                blockCount++;
//            } catch (Throwable t) {
//                exceptionCount++;
//                // 当使用ExceptionRatio异常比例来衡量资源是否处于稳定状态时, 需要显示的调用 Tracer.trace(t); 用于sentinel统计异常比例
//                Tracer.trace(t);
//            }

            // 这里不可以使用try-with-resource，因为在catch中需要用到entry
            Entry entry = null;
            try {
                entry = SphU.entry(RESOURCE_NAME);
                successCount++;
                if (i % 2 == 0) {
                    throw new RuntimeException("throw runtime ");
                }
            } catch (BlockException e1) {
                blockCount++;
            } catch (Throwable t) {
                exceptionCount++;
                // 当使用ExceptionRatio异常比例来衡量资源是否处于稳定状态时, 需要显示的调用 Tracer.trace(t); 用于sentinel统计异常比例
                Tracer.trace(t);
            } finally {
                if (entry != null) {
                    entry.exit();
                }
            }
        }
        SentinelDemo4Output output = new SentinelDemo4Output();
        System.out.println(MessageFormatUtil.format("Rest Service[{}], param[{}]!", this.getClass().getSimpleName(), input));
        output.setSuccessCount(successCount);
        output.setBlockCount(blockCount);
        output.setExceptionCount(exceptionCount);
        return null;
    }

    private void defineDegradeRule(SentinelDemo4Input input) {
        List<DegradeRule> rules = new ArrayList<>();
        DegradeRule rule = new DegradeRule();
        rule.setResource(RESOURCE_NAME);
        rule.setCount(input.getCount());
        rule.setGrade(input.getGrade());
        rule.setTimeWindow(input.getTimeWindow());
        rules.add(rule);
        DegradeRuleManager.loadRules(rules);
    }
}